﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using System.Threading;

using SpotItComponents;
using SpotItServerAPI;

using Vitruvian.Serialization;
using Vitruvian.Services;
using Vitruvian.Testing;
using Vitruvian.Logging;


namespace SpotItServerTester
{
    [ContainsTests("SystemTest.CategoryManagement")]
    public class CategoryManagerTester : BaseTester
    {
        public CategoryManagerTester() { }

        [OneTimeSetup]
        public void TestSuiteSetup()
        {
            base.EstablishConnectionToServer();

            base.WaitForAllDistributedServices();
            Assert.IsNotNull(accountManager);
            Assert.IsNotNull(symbolManager);
            Assert.IsNotNull(categoryManager);

            base.LoginInAsAdmin();
            Assert.IsNotNull(mySession);
            Assert.IsTrue(mySession.UserInfo.IsAdmin);
        }

        [Test(1)]
        private void Test_CategoryManager_Constructor_And_Lookup()
        {
            // Clear out all of the categories to start with
            OperationResult result = categoryManager.RemoveAllCategories(mySession);
            Assert.IsTrue(result.Success);

            // Add a few categories, using the admin session
            Category c1 = new Category("Nature");
            Category c2 = new Category("Animals", c1);
            Category c3 = new Category("Plants", c1);
            Category c4 = new Category("Trees", c3);

            result = categoryManager.Add(mySession, c1);
            Assert.IsTrue(result.Success);
            result = categoryManager.Add(mySession, c2);
            Assert.IsTrue(result.Success);
            result = categoryManager.Add(mySession, c3);
            Assert.IsTrue(result.Success);
            result = categoryManager.Add(mySession, c4);
            Assert.IsTrue(result.Success);

            // Get a list of all categories
            result = categoryManager.Lookup(mySession, null, null);
            Assert.IsTrue(result.Success);
            List<Category> categories = result.Data as List<Category>;
            Assert.IsNotNull(categories);
            Assert.IsEqual(4, categories.Count);

            // Get a list of categories beginning with a "pl"
            result = categoryManager.Lookup(mySession, "pl", null);
            Assert.IsTrue(result.Success);
            categories = result.Data as List<Category>;
            Assert.IsNotNull(categories);
            Assert.IsEqual(1, categories.Count);
            Assert.IsEqual("Plants", categories[0].Label);

            // Get a list of categories beginning with a "abc"
            result = categoryManager.Lookup(mySession, "abc", null);
            Assert.IsFalse(result.Success);

            // Get a list of categories in the Nature category
            result = categoryManager.Lookup(mySession, null, c1);
            Assert.IsTrue(result.Success);
            categories = result.Data as List<Category>;
            Assert.IsNotNull(categories);
            Assert.IsEqual(2, categories.Count);
            Assert.IsEqual("Animals", categories[0].Label);
            Assert.IsEqual("Plants", categories[1].Label);
        }

        [Test(2)]
        private void Test_CategoryManager_Remove_And_RemoveAll()
        {
            // Clear out all of the categories to start with
            OperationResult result = categoryManager.RemoveAllCategories(mySession);
            Assert.IsTrue(result.Success);

            // Add a few categories, using the admin session
            Category c1 = new Category("Nature");
            Category c2 = new Category("Animals", c1);
            Category c2a = new Category("Dogs", c2);
            Category c2b = new Category("Cats", c2);
            Category c3 = new Category("PlantS", c1);
            Category c3a = new Category("Trees", c3);
            Category c3b = new Category("Flowers", c3);
            Category c3c = new Category("Bushes", c3);

            Assert.IsTrue(categoryManager.Add(mySession, c1).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c2).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c2a).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c2b).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c3).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c3a).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c3b).Success);
            Assert.IsTrue(categoryManager.Add(mySession, c3c).Success);

            // Get a list of all categories
            result = categoryManager.Lookup(mySession, null, null);
            Assert.IsTrue(result.Success);
            List<Category> categories = result.Data as List<Category>;
            Assert.IsNotNull(categories);
            Assert.IsEqual(8, categories.Count);

            result = categoryManager.Remove(mySession, c3);
            Assert.IsTrue(result.Success);

            result = categoryManager.Lookup(mySession, null, null);
            Assert.IsTrue(result.Success);
            categories = result.Data as List<Category>;
            Assert.IsNotNull(categories);
            Assert.IsEqual(7, categories.Count);
            Assert.IsTrue(categories.Contains(c1));
            Assert.IsTrue(categories.Contains(c2));
            Assert.IsTrue(categories.Contains(c2a));
            Assert.IsTrue(categories.Contains(c2b));
            Assert.IsTrue(categories.Contains(c3a));
            Assert.IsTrue(categories.Contains(c3b));
            Assert.IsTrue(categories.Contains(c3c));

            // TODO: Check that 3a, 3b, 3c are now child of nature

            result = categoryManager.RemoveAllCategories(mySession);
            Assert.IsTrue(result.Success);

            result = categoryManager.Lookup(mySession, null, null);
            Assert.IsFalse(result.Success);
        }

    }
}
